www.gusucode.com > 相当专业的VB视频聊天程序源码程序 > 相当专业的VB视频聊天程序/ZX Messenger Whisper 源代码/ZX Messenger Whisper 源代码/Phone.dll/Phone.cpp

    // Phone.cpp : Defines the initialization routines for the DLL.
//

#include "stdafx.h"
#include "Phone.h"

#include "DataEx.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

//
//	Note!
//
//		If this DLL is dynamically linked against the MFC
//		DLLs, any functions exported from this DLL which
//		call into MFC must have the AFX_MANAGE_STATE macro
//		added at the very beginning of the function.
//
//		For example:
//
//		extern "C" BOOL PASCAL EXPORT ExportedFunction()
//		{
//			AFX_MANAGE_STATE(AfxGetStaticModuleState());
//			// normal function body here
//		}
//
//		It is very important that this macro appear in each
//		function, prior to any calls into MFC.  This means that
//		it must appear as the first statement within the 
//		function, even before any object variable declarations
//		as their constructors may generate calls into the MFC
//		DLL.
//
//		Please see MFC Technical Notes 33 and 58 for additional
//		details.
//

/////////////////////////////////////////////////////////////////////////////
// CPhoneApp

BEGIN_MESSAGE_MAP(CPhoneApp, CWinApp)
	//{{AFX_MSG_MAP(CPhoneApp)
		// NOTE - the ClassWizard will add and remove mapping macros here.
		//    DO NOT EDIT what you see in these blocks of generated code!
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CPhoneApp construction

CPhoneApp::CPhoneApp()
{
	// TODO: add construction code here,
	// Place all significant initialization in InitInstance
}


/////////////////////////////////////////////////////////////////////////////
// The one and only CPhoneApp object

CPhoneApp theApp;

/////////////////////////////////////////////////////////////////////////////
// CPhoneApp initialization

BOOL CPhoneApp::InitInstance()
{
	if (!AfxSocketInit())
	{
		AfxMessageBox(IDP_SOCKETS_INIT_FAILED);
		return FALSE;
	}

	return TRUE;
}

//
//自定义变量
//
//全局变量
CString RemoteHost;
long RemotePort;
HWAVEOUT hWaveOut;
bool m_Opened;
WAVEHDR WaveHdrOut[MAXWAVEBLOCK];
//局部变量
static WAVEHDR WaveHdrIn[MAXWAVEBLOCK];
static char WaveOutBuffer[MAXWAVEBLOCK][MAXWAVEBUFFER];//保存播音数据用内存块
static char WaveInBuffer[MAXWAVEBLOCK][MAXWAVEBUFFER];//记录录音数据用内存块
static HWAVEIN hWaveIn;
static CExchange* m_pChange;


static void CALLBACK waveInProc(HWAVEIN hwi, UINT uMsg, WORD dwInstance,
						 WAVEHDR* dwParam1, DWORD dwParam2)
{
	long result;
	char buffer[MAXWAVEBUFFER];
	long buf_len;

	switch(uMsg)
	{//判断回调类型
	case WIM_OPEN:
		//录音设备正常打开时,触发该事件
		//MessageBox(NULL,"Open success", "提示", MB_OK);
		break;
	case WIM_CLOSE:
		//录音设备正常关闭时,触发该事件
		//MessageBox(NULL,"Close success", "提示", MB_OK);
		break;
	case WIM_DATA:
		//录音设备返回数据时,触发该事件
		if(!waveInUnprepareHeader(hwi, dwParam1,sizeof(WAVEHDR)))
		{//可以释放内存。有的情况虽然返回数据,但不能释放内存,
		 //如使用同一个WAVEHDR增加多个内存块时,会出现上述情况
			memcpy(buffer, dwParam1->lpData , MAXWAVEBUFFER);//复制返回数据
			buf_len = dwParam1->dwBytesRecorded;//记录录音数据长度
			dwParam1->dwUser=0;//恢复设置
			dwParam1->dwBufferLength=MAXWAVEBUFFER;
			dwParam1->dwFlags=0;
			if(m_Opened)
			{//录音仍在继续
				result=waveInPrepareHeader(hwi,dwParam1,sizeof(WAVEHDR));
 				result=waveInAddBuffer(hwi,dwParam1,sizeof(WAVEHDR));
			}
		}
		if(buf_len > 0 && buf_len <= MAXWAVEBUFFER)
		{//有录音数据
			//发送录音数据
			m_pChange->SendTo(buffer, buf_len, RemotePort, LPCTSTR(RemoteHost));
		}
		break;
	}
};


void CALLBACK waveOutProc(HWAVEOUT hwo, UINT uMsg, WORD dwInstance,
						 WAVEHDR* dwParam1, DWORD dwParam2)
{
	switch(uMsg)
	{//判断回调类型
	case WOM_OPEN:
		//播音设备正常打开时,触发该事件
		//MessageBox(NULL,"Open success",NULL,MB_OK);
		break;
	case WOM_CLOSE:
		//播音设备正常关闭时,触发该事件
		//MessageBox(NULL,"Close success",NULL,MB_OK);
		break;
	case WOM_DONE:
		//内存播放完成时,触发该事件
		if(!waveOutUnprepareHeader(hwo, dwParam1, sizeof(WAVEHDR)))
		{
			//delete dwParam1->lpData;//删除语音数据内存
			//delete dwParam1;//删除结构定义内存
			m_pChange->DelDataBlock();//减少内存数量记数
		}
		break;
	}
};

long _stdcall StartPhone(char* HostAddress, long lPort, long rPort) 
{
	// TODO: Add your dispatch handler code here

	AFX_MANAGE_STATE(AfxGetStaticModuleState());

	long sta;
	int i;
	void _stdcall ClosePhone();

	if(m_Opened)
	//设备正在使用
		return -1;
	m_Opened = true;

	if(!strlen(HostAddress))
	//无主机地址
		return -2;
	else
	{
		RemoteHost = HostAddress;//保存主机地址
		RemotePort = rPort;//保存主机端口号
	}

	m_pChange = new CExchange;//创建Socket类,UDP套接字
	if(!m_pChange->Create(lPort, SOCK_DGRAM, FD_READ|FD_WRITE|FD_OOB))
	{//套接字创建失败
		return -3;
	}

	WAVEFORMATEX waveFormatEx;
		waveFormatEx.cbSize=0;
		waveFormatEx.nAvgBytesPerSec=16000;
		waveFormatEx.nBlockAlign=2;
		waveFormatEx.nChannels=1;
		waveFormatEx.nSamplesPerSec=8000;
		waveFormatEx.wBitsPerSample=16;
		waveFormatEx.wFormatTag=WAVE_FORMAT_PCM;

	//打开播音设备并开始播音
	for(i=0;i < MAXWAVEBLOCK; i++)
		WaveHdrOut[i].lpData=WaveOutBuffer[i];//设置播音数据内存区
	hWaveOut = NULL;
	if(waveOutOpen(&hWaveOut, WAVE_MAPPER, &waveFormatEx, (unsigned long)waveOutProc, 0L, CALLBACK_FUNCTION)) 
	{//播音设备打开失败,播音设备被其他程序占用
		ClosePhone();
		return 1;
	}

	hWaveIn = NULL;
	if(sta=waveInOpen(&hWaveIn, WAVE_MAPPER, &waveFormatEx, (unsigned long)waveInProc, 1L, CALLBACK_FUNCTION)) 
	{//录音设备打开失败,可能声卡不支持全双工。
		ClosePhone();
		return 2;
	}
	
	for(i=0;i < MAXWAVEBLOCK; i++)
	{//增加录音内存
		WaveHdrIn[i].lpData=WaveInBuffer[i];
		WaveHdrIn[i].dwBufferLength=MAXWAVEBUFFER;
		WaveHdrIn[i].dwFlags=0;
		WaveHdrIn[i].dwUser=0;
		if(waveInPrepareHeader(hWaveIn, &WaveHdrIn[i], sizeof(WAVEHDR)))
		{//无法锁定该内存
			ClosePhone();
			return 3;
		}; 
		if(waveInAddBuffer(hWaveIn,&WaveHdrIn[i],sizeof(WAVEHDR)))
		{//无法增加该内存
			ClosePhone();
			return 4;
		}
	}
	if(waveInStart(hWaveIn))
	{//无法开始录音
		ClosePhone();
		return 5;
	}

	return 0;
}

void _stdcall ClosePhone() 
{
	// TODO: Add your dispatch handler code here
try
{
	//AfxMessageBox("-1 ok");
	AFX_MANAGE_STATE(AfxGetStaticModuleState());
	//AfxMessageBox("0 ok");
	
	if(!m_Opened)//电话已经关闭
		return;
	m_Opened = false;//关闭电话使用标志
	AfxMessageBox("语音连接已断开。",MB_OK+64);
	//AfxMessageBox("1 ok");
	if(hWaveIn){
		waveInStop(hWaveIn);//停止录音
		waveInReset(hWaveIn);//清空录音缓存
		waveInClose(hWaveIn);//关闭录音设备
		hWaveIn = NULL;
	}
	//AfxMessageBox("2 ok");
	if(m_pChange)
		m_pChange->ShutDown();//停止接收数据
	//AfxMessageBox("3 ok");
	if(hWaveOut)
	{
		waveOutReset(hWaveOut);//清空声音输出缓存
		waveOutClose(hWaveOut);//关声音输出设备
		hWaveOut = NULL;
	}
	//AfxMessageBox("4 ok");
	if(m_pChange)
	{
		BYTE Buffer[50];
		while (m_pChange->Receive(Buffer,50) > 0);//清空未接收数据
		delete m_pChange;//删除网络对象
		m_pChange = NULL;
	}
	
}catch(...)
{


}
}